/*
#Copyright (c) 2013, Philippe Bordron <philippe.bordron@gmail.com>
#
# This file is part of SIPPER.
#
# DCC is free software: you can redistribute it and/or modify
# it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# DCC is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU LESSER GENERAL PUBLIC LICENSE for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# along with SIPPER.  If not, see <http://www.gnu.org/licenses/>
*/
package combi.sipper.io;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import cern.colt.matrix.DoubleMatrix2D;
import cern.colt.matrix.impl.DenseDoubleMatrix2D;

public class IODistanceMatrix {

	private List<String> id;
	private DoubleMatrix2D matrix;
	private final static double defaultValue = Double.NaN;
	
	
/*	public IODistanceMatrix()
	{
		name="";
		id = new ArrayList<String>();
		matrix = new DenseDoubleMatrix2D(id.size(),id.size());
	}*/
	
	private IODistanceMatrix(List<String> id)
	{
		this.id = id;
		matrix = new DenseDoubleMatrix2D(id.size(),id.size());
	}

	public List<String> getIDs()
	{
		return id;
	}
	
	public DoubleMatrix2D getMatrix()
	{
		return matrix;
	}

	private void setValue(int l, int c, double value)
	{
		this.matrix.setQuick(l, c, value);
	}
	
	private double getValue(int l, int c)
	{
		return this.matrix.getQuick(l, c);
	}
	
	public static IODistanceMatrix load(String fileIn)
	{
		List<String> ids = new ArrayList<String>();
		IODistanceMatrix result = new IODistanceMatrix(ids);
		try
		{
			BufferedReader in = new BufferedReader (new FileReader (fileIn));
			String ch;
			if ((ch = in.readLine()) != null)
			{
				ids = new ArrayList<String>(java.util.Arrays.asList(ch.split("\t")));
			}
			result = new IODistanceMatrix(ids);
			int i = 0;
			int nbElem = ids.size();
			while ((ch = in.readLine()) != null)
			{
				String[] s = ch.split("\t");
				//System.err.println(s.length);
				for (int j = i; j<nbElem; j++)
				{
					try{
						Double val =new Double(s[j]);
						//if (val == 0.0)
						//{
						//	System.err.println("0.0 value at " + i+"," +j);
						//}
						result.setValue(i, j, val);
						result.setValue(j, i, val);
					}
					catch(NumberFormatException ex)
					{
						result.setValue(i, j, defaultValue);
						result.setValue(j, i, defaultValue);
					}
				}
				i++;
				//System.err.println((100-(nbElem-i)*(nbElem-i-1)*100/(nbElem * (nbElem -1))) + "%");
			}
			in.close();
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
		return result;
	}
	
	public void clear()
	{
		id.clear();
	}
	
	
	public void export(String fileOut)
	{
		BufferedWriter out;
		try {
			out = new BufferedWriter(new FileWriter(fileOut));
			out.write(id.toString().replace(", ", "\t").replace("[","").replace("]","") + "\n");
			int last = id.size();
			for (int i = 0; i<last; i++)
			{
				for (int j = 0; j<last-1; j++)
				{
					out.write(this.getValue(i,j) + "\t");
				}
				out.write(this.getValue(i,last-1) + "\n");
			}
			out.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args) {
		IODistanceMatrix distances = IODistanceMatrix.load(args[0]);
		System.out.println(distances.getIDs());
		System.out.println(distances.getMatrix());
		distances.export(args[1]);
		
//		for (int i = 1; i<100; i++)
//		{
//			int x = Math.round(new Float(Math.random()*distances.getIDs().size()));
//			int y = Math.round(new Float(Math.random()*distances.getIDs().size()));
//			System.out.println("[" + x + ","+ y+ "]=" + distances.matrix.getQuick(x,y));
//		}
	}
	
}
